-- SPDX-FileCopyrightText: Adam Evyčędo
--
-- SPDX-License-Identifier: AGPL-3.0-or-later

---@diagnostic disable-next-line: unused-local, lowercase-global
function getUpdates(tripID, sequence, stopID, stopCode)
	local http = require("http")
	local json = require("json")

	local error_struct = {
		httpResponseCode = 0,
		message = "",
		willNextRequestFail = false
	}

	local rbls_raw = ""
	local i = 0
	for m in string.gmatch(stopCode, "([^|]+)") do
		if i == 1 then
			rbls_raw = m
			break
		end
		i = i + 1
	end

	local rbls = {}
	i = 1
	for m in string.gmatch(rbls_raw, "([^,]+)") do
		rbls[i] = m
		i = i + 1
	end

	local updates = {
		areTripsInTimetable = false,
		updates = {},
		alerts = {}
	}
	updates.updates[''] = {
		time = "000000",
		stopID = stopCode,
		delay = 0,
		timetableRelationship = 1,
		vehicleStatus = {
			lineName = "",
			headsign = ""
		}
	}
	updates.alerts[''] = { {
		timeRanges = {
			{ startDate = '0001-01-01T00:00:00.000Z', endDate = '9999-12-31T23:59:59.999Z' }
		},
		headers = {
			und = ''
		},
		descriptions = {
			und = ''
		},
		urls = {
			und = ''
		},
		cause = 0,
		effect = 0
	} }

	for _, rbl in ipairs(rbls) do
		local response, error_message = http.get("https://www.wienerlinien.at/ogd_realtime/monitor", {
			query = "stopId=" .. rbl,
			timeout = "30s"
		})

		if response == nil then
			error_struct.message = "while getting updates: " .. error_message
			local error_json, _ = json.encode(error_struct)
			return "", error_json
		end

		if response.status_code ~= 200 then
			error_struct.message = "api returned code " .. response.status_code .. "; " .. response.body
			error_struct.httpResponseCode = response.status_code
			error_struct.willNextRequestFail = true
			local error_json, _ = json.encode(error_struct)
			return "", error_json
		end

		---@diagnostic disable-next-line: redefined-local
		local struct, error_message = json.decode(response.body)

		if struct == nil then
			error_struct.message = "while decoding updates: " .. error_message
			local error_json, _ = json.encode(error_struct)
			return "", error_json
		end


		for _, entry in ipairs(struct.data.monitors) do
			for _, l in ipairs(entry.lines) do
				for _, d in ipairs(l.departures.departure) do
					if d.departureTime ~= nil and d.vehicle ~= nil then
						local timeReal = nil
						local timePlanned = tonumber(string.sub(d.departureTime.timePlanned, 12, 13), 10)*3600 + tonumber(string.sub(d.departureTime.timePlanned, 15, 16), 10)*60 + tonumber(string.sub(d.departureTime.timePlanned, 18, 19), 10)
						local departureTime = string.sub(d.departureTime.timePlanned, 12, 13) .. string.sub(d.departureTime.timePlanned, 15, 16) .. string.sub(d.departureTime.timePlanned, 18, 19)
						local departureDelay = 0
						local relationship = 1
						if d.departureTime.timeReal ~= nil then
							timeReal = tonumber(string.sub(d.departureTime.timeReal, 12, 13), 10)*3600 + tonumber(string.sub(d.departureTime.timeReal, 15, 16), 10)*60 + tonumber(string.sub(d.departureTime.timeReal, 18, 19), 10)
							departureTime = string.sub(d.departureTime.timeReal, 12, 13) .. string.sub(d.departureTime.timeReal, 15, 16) .. string.sub(d.departureTime.timeReal, 18, 19)
							departureDelay = timeReal - timePlanned
							relationship = 0
	          end
						local congestion_level = 1
						if d.vehicle.trafficjam then
							congestion_level = 3
						end
						local accessibility = 3
						if d.vehicle.barrierFree == true or d.vehicle.foldingRamp == true then
							accessibility = 2
						end
						updates.updates[d.departureTime.timePlanned .. d.vehicle.platform .. d.vehicle.linienId] = {
							time = departureTime,
							stopID = stopCode,
							delay = departureDelay,
							timetableRelationship = relationship,
							vehicleStatus = {
								lineName = d.vehicle.name,
								headsign = d.vehicle.towards,
								congestionLevel = congestion_level,
								wheelchairAccessibility = accessibility
							}
						}
					end
				end
			end
		end
	end

	---@diagnostic disable-next-line: redefined-local
	local result, error_message = json.encode(updates)

	if result == nil then
		error_struct.message = "while encoding result: " .. error_message
		local error_json, _ = json.encode(error_struct)
		return "", error_json
	end

	return result, ""
end
